# Built-In Example AI

# Title: DirectTurtle
# Author: Adam Rumpf
# Version: 1.0.1
# Date:5/13/2020

import game.tcturtle
import math
import random

class CombatTurtle(game.tcturtle.TurtleParent):
    """Direct combat turtle.

    Its main strategy is to try to move directly towards the opponent, firing
    missiles when it has clear line of sight. It does not pay much attention
    to obstacles.
    """

    #-------------------------------------------------------------------------

    def class_name():
        """CombatTurtle.class_name() -> str
        Static method to return the name of the Combat Turtle AI.
        """

        return "ct_huanledoudizu"

    #-------------------------------------------------------------------------

    def class_desc():
        """CombatTurtle.class_desc() -> str
        Static method to return a description of the Combat Turtle AI.
        """

        return "做人不能太攀比，要比就要比学习"

    #-------------------------------------------------------------------------

    def class_shape():

        """CombatTurtle.class_shape() -> (int or tuple)
        Static method to define the Combat Turtle's shape image.

        The return value can be either an integer or a tuple of tuples.

        Returning an integer index selects one of the following preset shapes:
            0 -- arrowhead (also default in case of unrecognized index)
            1 -- turtle
            2 -- plow
            3 -- triangle
            4 -- kite
            5 -- pentagon
            6 -- hexagon
            7 -- star

        A custom shape can be defined by returning a tuple of the form
        (radius, angle), where radius is a tuple of radii and angle is a tuple
        of angles (in radians) describing the polar coordinates of a polygon's
        vertices. The shape coordinates should be given for a turtle facing
        east.
        """
        x = 0.6
        pi = math.pi

        radius = (20 * x, 35 * x, 35 * x, 20 * x, 10 * x, 10 * x, 10 * x, 10 * x, 0, 35 * x, 35 * x, 0)
        angle = (0, 16 * pi / 18, -16 * pi / 18, 0, 0, pi / 2, -pi / 2, 0, 0, 3 * pi / 4, -3 * pi / 4, 0)
        return (radius, angle)


    #=========================================================================

    def setup(self):
        """CombatTurtle.setup() -> None
        Initialization code for Combat Turtle.
        """

        # 最低血量，低于该值时转向撤离
        self.min_health = 60
        # 判断此时是否处于危险状态，当为true时直接跑
        self.danger_flag = False

        # 追踪截至距离，大于该距离时移动
        self.pursuit_range = 0.85 * self.missile_range

        self.head = random.randrange(-179, 181)

        self.nose_rel = (8, 0.0)  # just ahead of turtle's front
        self.hand_rel = (8, math.pi / 2)  # to left of turtle

        self.time = 1
    #-------------------------------------------------------------------------

    def step(self):
        """CombatTurtle.setup() -> None
        Step event code for Combat Turtle.
        """
        # 血量低于某个值 && 此时血量低于对手
        if  self.health < self.min_health and self.health < self.other_health:

            # self.turn_towards(self.head)
            self.turn_towards(self.head)
            self.forward(self.max_speed)
            self.time+=1
            # 拉开一定的身位，当小于某个计数值时再转向对手射击
            if self.time >= 180:
                self.turn_toward()
                self.forward(self.max_speed)
                self.shoot()

            #置此时的危险状态，不执行下面的代码
            self.danger_flag = True

        # 不危险时的策略
        if (self.danger_flag is False and self.distance() <= self.pursuit_range and
                self.line_of_sight()):

            # 在定义的追击范围内直接追击
            self.turn_towards()

            # 与对手距离大于某个给定值时移动
            if self.distance() > 3 * self.missile_radius:
                self.forward()
            else:
                self.backward()

            if self.can_shoot and abs(self.relative_heading_towards()) <= 5 \
                    and self.line_of_sight() :
                    # and self.distance() <= self.missile_range * 1.25:
                    self.shoot()
        # 贴着墙走
        elif self.danger_flag is False:
            # Calculate Cartesian coordinates of nose and hand
            nose = ((self.x + self.nose_rel[0] *
                     math.cos(math.radians(self.heading) + self.nose_rel[1])),
                    (self.y - self.nose_rel[0] *
                     math.sin(math.radians(self.heading) + self.nose_rel[1])))
            hand = ((self.x + self.hand_rel[0] *
                     math.cos(math.radians(self.heading) + self.hand_rel[1])),
                    (self.y - self.hand_rel[0] *
                     math.sin(math.radians(self.heading) + self.hand_rel[1])))

            # Determine behavior based on whether nose and hand are clear
            if self.free_space(nose) == True:
                # Move forward when clear ahead
                self.forward()
            else:
                if self.free_space(hand) == True:
                    # If free to left, turn left
                    self.left()
                    self.forward()
                else:
                    # If blocked ahead and to left, turn right
                    self.right()
                    self.forward()